package cn.server.impl;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.server.conf.ReceiveServerParam;

public class ReceiveServer extends BaseServer {
	/**
	 * Logger for this class
	 */
	private static final Log logger = LogFactory.getLog(ReceiveServer.class);

	@Override
	public void startServer() {
		super.startServer();
		int port = param.getPort();
		ReceiveServerParam rsp = (ReceiveServerParam) param;
		String handlers = rsp.getHandlers();
		if (StringUtils.isBlank(handlers))
			throw new RuntimeException("no handler is set!");
		final String[] cls = handlers.split(",");
		EventLoopGroup bossGroup = new NioEventLoopGroup(param.getMaxThread());
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap server = new ServerBootstrap();
			server.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
					.option(ChannelOption.SO_BACKLOG, 1024).childOption(ChannelOption.SO_KEEPALIVE, true)
					.childOption(ChannelOption.TCP_NODELAY, true).localAddress(port)
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						public void initChannel(SocketChannel ch) throws Exception {
							ChannelPipeline p = ch.pipeline();
							for (int i = 0; i < cls.length; i++) {
								p.addLast("handler" + i, (ChannelHandler) Class.forName(cls[i]).newInstance());
							}
						}
					});
			ChannelFuture f = server.bind().sync();
			f.channel().closeFuture().sync();
		} catch (Throwable e) {
			logger.error("error start server!", e);
			throw new RuntimeException("error start server!", e);
		} finally {
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}
}
